home *** CD-ROM | disk | FTP | other *** search
- /* COMPLETELY rewritten by Dave Stampe Dec. 1993, */
- /* used to be render.c, now split off to uservid.c and this file */
-
- // This code is the refresh-screen call. All the other stuff was
- // moved to uservid.c
- // Also has Dave's axis-compass (much improved) and the new
- // prerender/postrender support
-
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
-
-
- #include <stdio.h>
- #include <dos.h>
- #include <stdlib.h> /* labs */
-
- #include "f3dkitd.h"
-
- #include "vr_api.h"
- #include "pcdevice.h" // register_render_start,end
- #include "intmath.h"
- #include "splits.h"
-
- #define MAIN_VGA 1 /* for multi-VGA only */
- #define LEFT_VGA 2
- #define RIGHT_VGA 4
- #define ALL_VGA 7
-
- #define MONOSCOPIC 0 /* stereo types */
- #define SWITCHED 1
- #define SPLITLR 3
- #define SEPARATE 5
-
- extern struct Screeninfo *screeninfo;
-
- extern int swap_eyes;
-
- extern int show_location, show_compass, show_framerate; // options
- extern int use_glove;
-
- extern void user_draw_line(int x1, int y1, int x2, int y2, int color);
-
-
- // draw an axis compass
- // placed at abs. screen position and size
- // has visibility sort, but no perspective
- // usually just draw one eye for stereo,
- // since results are disappointing without perspective
-
-
- static do_axis(int xc, int yc, int x, int y, int bcolor, int xcolor, char c)
- {
- char st[] = "x";
-
- st[0] = c;
-
- if (current_orientation & XFLIP)
- {
- user_draw_line(xc,yc,xc-x,yc-y,bcolor);
- user_text(xc-x-5,yc-y,bcolor,st);
- user_draw_line(xc-1,yc+1,xc-1-x,yc+1-y,xcolor);
- user_text(xc-x-5-1,yc-y+1,xcolor,st);
- }
- else
- {
- user_draw_line(xc,yc,x+xc,yc-y,bcolor);
- user_text(x+xc+5,yc-y,bcolor,st);
- user_draw_line(xc+1,yc+1,x+xc+1,yc-y+1,xcolor);
- user_text(x+xc+5+1,yc-y+1,xcolor,st);
- }
- }
-
- // xc,yx : screen location of center
- // V : viewport
- // xcolor,ycolor,zcolor: color of axes
- // bcolor: "shadow" color
-
- void coord_ref(WORD xc, WORD yc, WORD size, VIEW *v,
- WORD xcolor, WORD ycolor, WORD zcolor, WORD bcolor)
- {
- MATRIX m;
- int i;
- long x[3], y[3], z[3]; // coords from axes
- int order[3] = {0,1,2}; // sort terms
- int color[3];
- char label[3] = {'x','y','z'}; // labels
-
- if (show_compass == 0) return;
-
- color [0] = xcolor;
- color [1] = ycolor;
- color [2] = zcolor;
-
- view_to_matrix(v,m); // transform for axes
- m[3][0] = m[3][1] = m[3][2] = 0;
- matrix_transpose(m,m);
-
-
- x[0] = size; y[0] = 0; z[0] = 0; // axes to screen locations
- x[1] = 0; y[1] = size; z[1] = 0;
- x[2] = 0; y[2] = 0; z[2] = size;
-
- matrix_point(m, &x[0], &y[0], &z[0]);
- matrix_point(m, &x[1], &y[1], &z[1]);
- matrix_point(m, &x[2], &y[2], &z[2]);
- // aspect ratio fixup
- y[0] = mulmuldiv(y[0],screeninfo->aspect,65536L);
- y[1] = mulmuldiv(y[1],screeninfo->aspect,65536L);
- y[2] = mulmuldiv(y[2],screeninfo->aspect,65536L);
-
- if (z[order[0]]<=z[order[1]]) // sort by depth so deepest first
- {
- i = order[0];
- order[0] = order[1];
- order[1] = i;
- }
- if (z[order[0]]<=z[order[2]])
- {
- i = order[0];
- order[0] = order[2];
- order[2] = i;
- }
- if (z[order[1]]<=z[order[2]])
- {
- i = order[1];
- order[1] = order[2];
- order[2] = i;
- }
-
- do_axis(xc,yc, x[order[0]], y[order[0]], bcolor, color[order[0]], label[order[0]]);
- do_axis(xc,yc, x[order[1]], y[order[1]], bcolor, color[order[1]], label[order[1]]);
- do_axis(xc,yc, x[order[2]], y[order[2]], bcolor, color[order[2]], label[order[2]]);
- }
-
-
- static VIEW left_view, right_view;
-
- void stop_stereo()
- {
- right_page = left_page = current_video_page; /* stop stereo for now */
- }
-
-
-
-
- //////////////////////////////////////////
- /// THESE ROUTINES LET YOU CONTROL HOW THE
- /// SCREEN IS CLEARED AND WHAT IS DISPLAYED
- /// THE ARGUMENTS ARE:
- /// v : the view being draw. left/right eye views are different
- /// vpage: the video page being drawn
- /// isfirst, islast: 1 if this is the first/last access to the
- /// video page. Useful for toggling screen
- /// clears etc. when several views are on the
- /// same page
- /// whicheye: 0 for left eye/mono, 1 for right eye view
- ///
-
-
- // found in <USCREEN.C>
-
- // This is called before drawing objects. It should
- // at least clear the screen
-
- void prerender_process(VIEW *v, unsigned vpage, WORD isfirst, WORD whicheye);
-
- // This is called after drawing objects. It can be used
- // to put up status, etc.
- // lots of if() stuff, but just because we're supporting
- // so many stereo types
-
- void postrender_process(VIEW *v, unsigned vpage, WORD islast, WORD whicheye);
-
-
-
- // where to save the screen while using menus
- WORD screen_save_video_page = 1;
- static WORD last_visible_video_page = 0;
- BOOL screen_has_been_saved = FALSE;
-
-
- extern int reframe;
-
- void screen_refresh(CAMERA *c) /* now does stereo drawing */
- {
- int mxpge = 2;
- char st[100];
- VIEW *v;
- BOOL was_visible;
-
- register_render_start();
-
- screen_save_video_page = current_video_page;
- last_visible_video_page = current_video_page;
-
- if (screeninfo->pages < 3) mxpge = 1; else mxpge = 2;
- if(mxpge<2) vsync();
-
- if (stereo_type == MONOSCOPIC)
- {
- current_video_page++;
- if (current_video_page > mxpge) current_video_page = 0;
- was_visible = last_cursor_hide(current_video_page);
-
- set_drawpage(current_video_page);
-
- v = select_camera_view(c,0);
- prerender_process(v, current_video_page, 1, 0);
- render_split(global_world_root, v);
- postrender_process(v, current_video_page, 1, 0);
- set_vpage(current_video_page);
- }
- else if (stereo_type==SPLITLR)
- {
- current_video_page++;
- if (current_video_page > mxpge) current_video_page = 0;
-
- was_visible = last_cursor_hide(current_video_page);
- v = select_camera_view(c,LEFT_EYE);
- set_drawpage(current_video_page);
- prerender_process(v, current_video_page, 1, 0&LEFT_EYE);
- render_split(global_world_root, v);
- postrender_process(v, current_video_page, 0, LEFT_EYE);
-
- v = select_camera_view(c,RIGHT_EYE);
- set_drawpage(current_video_page);
- prerender_process(v, current_video_page, 0, RIGHT_EYE);
- set_drawpage(current_video_page);
- render_split(global_world_root, v);
- postrender_process(v, current_video_page, 1, RIGHT_EYE);
-
- set_vpage(current_video_page);
-
- }
- else if (stereo_type == SWITCHED)
- {
- current_video_page = current_video_page ^ 2; // need 4 pages for this!
-
- was_visible = last_cursor_hide(current_video_page);
- v = select_camera_view(c,LEFT_EYE);
- while ((has_switched&1) == 0) if (kbhit()) break; // wait if not seen yet
- set_drawpage(current_video_page);
- prerender_process(v, current_video_page, 1, LEFT_EYE);
- render_split(global_world_root, v);
- postrender_process(v, current_video_page, 1, LEFT_EYE);
-
- v = select_camera_view(c,RIGHT_EYE);
- while ((has_switched&2) == 0) if (kbhit()) break;
- set_drawpage(current_video_page+1);
- prerender_process(v, current_video_page+1, 1, RIGHT_EYE);
- render_split(global_world_root, v);
- postrender_process(v, current_video_page+1, 1, RIGHT_EYE);
-
- disable();
- if (swap_eyes)
- {
- left_page = current_video_page+1; /* display them now */
- right_page = current_video_page;
- }
- else
- {
- left_page = current_video_page;
- right_page = current_video_page+1;
- }
- has_switched = 0;
- enable();
- }
- else if (stereo_type == SEPARATE) // seperate VGA buffers
- {
- current_video_page++;
- if (current_video_page > mxpge) current_video_page = 0;
-
- was_visible = last_cursor_hide(current_video_page);
- set_drawpage(current_video_page);
- VGA_select(swap_eyes ? RIGHT_VGA : LEFT_VGA);
- v = select_camera_view(c,LEFT_EYE);
- prerender_process(v, current_video_page, 1, LEFT_EYE);
- render_split(global_world_root, v);
- postrender_process(v, current_video_page, 1, LEFT_EYE);
-
- VGA_select(swap_eyes ? LEFT_VGA : RIGHT_VGA);
- v = select_camera_view(c,RIGHT_EYE);
- prerender_process(v, current_video_page, 1, RIGHT_EYE);
- render_split(global_world_root, v);
- postrender_process(v, current_video_page, 1, RIGHT_EYE);
-
- VGA_select(LEFT_VGA);
- set_vpage(current_video_page);
- VGA_select(RIGHT_VGA);
- set_vpage(current_video_page);
- VGA_select(MAIN_VGA); // usually same as left
- }
-
- register_render_end();
-
- cursor_show(); // draw to current page
- set_drawpage(current_video_page);
- screen_has_been_saved = FALSE;
- }
-
-
-